#include<stdio.h>
#include <string.h>
#include<stdlib.h>

typedef struct Student {
    int age;
    char name[64];
} Student ;

struct dynaArrayMer {
    //二级指针，管理指针数组。指针指向数组的每个元素
    void **arrpp;
    //容量
    int capacity;
    //大小
    int size;
};

/**
 * 初始化动态数组
 * @param capacity 容量
 * @return
 */
struct dynaArray *initArray(int capacity) {
    if (capacity <= 0) {
        return NULL;
    }
    //给动态数组管理者开辟空间
    struct dynaArrayMer *arrayManager = malloc(sizeof(struct dynaArrayMer));
    if (arrayManager == NULL) {
        return NULL;
    }
    arrayManager->capacity = capacity;
    arrayManager->size = 0;

    //管理堆区数组的每个指针
    arrayManager->arrpp = malloc(sizeof(void *) * arrayManager->capacity);
    return arrayManager;
}

/**
 * 数组指定位置插入数据
 * @param arrayManager
 * @param pos index=pos
 * @param data 数据
 */
void insertArray(struct dynaArrayMer *arrayManager, int pos, void *data) {
    if (data == NULL) {
        return;
    }
    if (pos < 0 || pos > arrayManager->size) {
        //无效的位置，尾插法
        pos = arrayManager->size;
    }

    if (arrayManager->size > arrayManager->capacity) {
        //满载，开辟新的内存，将旧的数据拷贝到新的内存上
        int newSize = arrayManager->capacity * 2;

        //开辟的新的二级指针空间（本质数指针数组）,malloc开辟的空间是连续的
        //void * arr=malloc(sizeof(void *) * newSize);
        //void **newArrpp=&arr;
        void **newArrpp = malloc(sizeof(void *) * newSize);
        //二级指针拷贝，属于值拷贝,所以二级指针就可以用上了,拷贝的还是堆取地址
        memcpy(newArrpp, arrayManager->arrpp, sizeof(void *) * arrayManager->capacity);

        //释放旧的空间
        free(arrayManager->arrpp);
        //指向新的空间
        arrayManager->arrpp = newArrpp;
        arrayManager->capacity = newSize;
    }

    //把指定的pos之后的数据往后移动
    for (int i = arrayManager->size - 1; i >= pos; i--) {
        arrayManager->arrpp[i + 1] = arrayManager->arrpp[i];
    }
    arrayManager->arrpp[pos] = data;
    arrayManager->size++;

}

/**
 * 删除数组元素,按照角标删除
 * @param arrayManager
 * @param pos
 */
void removeArray(struct dynaArrayMer *arrayManager, int pos) {
    if (arrayManager == NULL) {
        return;
    }
    if (arrayManager->arrpp == NULL) {
        return;
    }
    for (int i = pos; i < arrayManager->size - 1; ++i) {
        //将pos后面的数据向前移动
        if (pos == arrayManager->size - 1) {
            void *item = arrayManager->arrpp[pos];
            free(item);
            item = NULL;
        }
        arrayManager->arrpp[i] = arrayManager->arrpp[i + 1];
    }
    arrayManager->size--;
}

int compareArrayValue(void *data1, void *data2) {
    struct Student *stu1 = data1;
    struct Student *stu2 = data2;
    return strcmp(stu1->name, stu2->name) == 0 && stu1->age == stu2->age;
}

/**
 * 按照值删除
 * @param arrayManager
 * @param data
 * @return
 */
void removeArrayByValue(struct dynaArrayMer *arrayManager, void *data) {
    if (arrayManager == NULL) {
        return;
    }
    if (arrayManager->arrpp == NULL) {
        return;
    }

    for (int i = 0; i < arrayManager->size - 1; ++i) {
        int eq=compareArrayValue(arrayManager->arrpp[i],data);
        if(eq==0){
            removeArray(arrayManager,i);
        }
    }
}

/**
 * 销毁数组
 * @param arrayManager
 */
void destroyArray(struct dynaArrayMer *arrayManager) {
    if (arrayManager == NULL) {
        return;
    }
    if (arrayManager->arrpp == NULL) {
        return;
    }
    free(arrayManager->arrpp);
    arrayManager->arrpp = NULL;
}

void main(){
    Student student1={1,"q001"};
    Student student2={2,"q002"};
    Student student3={3,"q003"};
    Student student4={4,"q004"};

    struct dynaArray * array=initArray(5);
    insertArray(array,0,&student1);
    insertArray(array,1,&student2);
    insertArray(array,2,&student3);
    insertArray(array,3,&student4);
}

